package proxy

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/sirupsen/logrus"
)

// 超时时间配置常量
const (
	DefaultTimeout        = 30 * time.Second  // 默认请求超时时间
	UploadTimeout         = 300 * time.Second // 文件上传等长时间操作的超时时间
	MaxTimeout           = 600 * time.Second // 最大允许的超时时间
	IdleConnTimeout      = 90 * time.Second  // 空闲连接超时时间
	TLSHandshakeTimeout  = 10 * time.Second  // TLS握手超时时间
	ResponseHeaderTimeout = 10 * time.Second  // 响应头超时时间
)

// Engine HTTP代理引擎
type Engine struct {
	logger  *logrus.Logger
	client  *http.Client
	metrics *Metrics
}

// Metrics 代理指标
type Metrics struct {
	TotalRequests   int64
	SuccessRequests int64
	FailedRequests  int64
	AverageLatency  time.Duration
	LastRequestTime time.Time
}

// HTTPRequest HTTP请求结构
type HTTPRequest struct {
	Method  string            `json:"method"`
	URL     string            `json:"url"`
	Headers map[string]string `json:"headers"`
	Body    string            `json:"body"`
	Timeout int               `json:"timeout"`
}

// HTTPResponse HTTP响应结构
type HTTPResponse struct {
	StatusCode     int               `json:"status_code"`
	Headers        map[string]string `json:"headers"`
	Body           string            `json:"body"`
	Success        bool              `json:"success"`
	Error          string            `json:"error,omitempty"`
	ResponseTimeMs int64             `json:"response_time_ms"`
}

// NewEngine 创建新的代理引擎
func NewEngine(logger *logrus.Logger) *Engine {
	client := &http.Client{
		Timeout: DefaultTimeout,
		Transport: &http.Transport{
			MaxIdleConns:        100,
			MaxIdleConnsPerHost: 10,
			IdleConnTimeout:     IdleConnTimeout,
			TLSHandshakeTimeout: TLSHandshakeTimeout,
			ResponseHeaderTimeout: ResponseHeaderTimeout,
		},
	}

	return &Engine{
		logger:  logger,
		client:  client,
		metrics: &Metrics{},
	}
}

// PerformRequest 处理HTTP请求
func (e *Engine) PerformRequest(ctx context.Context, req *HTTPRequest) (*HTTPResponse, error) {
	startTime := time.Now()
	e.metrics.TotalRequests++
	e.metrics.LastRequestTime = startTime

	e.logger.WithFields(logrus.Fields{
		"method": req.Method,
		"url":    req.URL,
	}).Info("Performing HTTP request")

	if err := e.validateRequest(req); err != nil {
		e.metrics.FailedRequests++
		return e.createErrorResponse(http.StatusBadRequest, fmt.Sprintf("Invalid request: %v", err), startTime), nil
	}

	// 设置请求超时时间
	requestTimeout := DefaultTimeout
	if req.Timeout > 0 {
		requestTimeout = time.Duration(req.Timeout) * time.Second
		// 限制最大超时时间
		if requestTimeout > MaxTimeout {
			requestTimeout = MaxTimeout
		}
	}

	// 创建带超时的context
	requestCtx, cancel := context.WithTimeout(ctx, requestTimeout)
	defer cancel()

	httpReq, err := e.createHTTPRequest(requestCtx, req)
	if err != nil {
		e.metrics.FailedRequests++
		return e.createErrorResponse(http.StatusInternalServerError, fmt.Sprintf("Failed to create HTTP request: %v", err), startTime), nil
	}

	e.logger.WithFields(logrus.Fields{
		"url": req.URL,
		"method": req.Method,
		"timeout": requestTimeout.String(),
	}).Debug("Sending HTTP request")

	resp, err := e.client.Do(httpReq)
	if err != nil {
		e.metrics.FailedRequests++
		e.logger.WithFields(logrus.Fields{
			"url": req.URL,
			"error": err.Error(),
		}).Error("Failed to send HTTP request")
		return e.createErrorResponse(http.StatusServiceUnavailable, fmt.Sprintf("Failed to send HTTP request: %v", err), startTime), nil
	}
	defer resp.Body.Close()

	e.logger.WithFields(logrus.Fields{
		"url": req.URL,
		"status_code": resp.StatusCode,
	}).Debug("Received HTTP response")

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		e.metrics.FailedRequests++
		return e.createErrorResponse(http.StatusInternalServerError, fmt.Sprintf("Failed to read response body: %v", err), startTime), nil
	}

	response := e.createSuccessResponse(resp, body, startTime)
	e.metrics.SuccessRequests++

	latency := time.Since(startTime)
	e.updateAverageLatency(latency)

	e.logger.WithFields(logrus.Fields{
		"status_code":   response.StatusCode,
		"response_time": response.ResponseTimeMs,
	}).Info("HTTP request performed successfully")

	return response, nil
}

func (e *Engine) validateRequest(req *HTTPRequest) error {
	// 简化验证，移除所有安全限制
	if req.URL == "" {
		return fmt.Errorf("URL is required")
	}
	parsedURL, err := url.Parse(req.URL)
	if err != nil {
		return fmt.Errorf("invalid URL: %w", err)
	}
	if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
		return fmt.Errorf("unsupported scheme: %s", parsedURL.Scheme)
	}
	if req.Method == "" {
		return fmt.Errorf("method is required")
	}
	// 移除主机、方法、请求头等安全限制
	return nil
}

func (e *Engine) createHTTPRequest(ctx context.Context, req *HTTPRequest) (*http.Request, error) {
	var body io.Reader
	if req.Body != "" {
		body = strings.NewReader(req.Body)
	}

	// 简化超时逻辑，使用HTTP客户端的全局超时设置
	httpReq, err := http.NewRequestWithContext(ctx, strings.ToUpper(req.Method), req.URL, body)
	if err != nil {
		return nil, err
	}

	for key, value := range req.Headers {
		httpReq.Header.Set(key, value)
	}

	if httpReq.Header.Get("User-Agent") == "" {
		httpReq.Header.Set("User-Agent", "MCP-HTTP-Proxy/1.0")
	}

	return httpReq, nil
}

func (e *Engine) createSuccessResponse(resp *http.Response, body []byte, startTime time.Time) *HTTPResponse {
	headers := make(map[string]string)
	for key, values := range resp.Header {
		if len(values) > 0 {
			headers[key] = values[0]
		}
	}

	return &HTTPResponse{
		StatusCode:     resp.StatusCode,
		Headers:        headers,
		Body:           string(body),
		Success:        resp.StatusCode >= 200 && resp.StatusCode < 400,
		ResponseTimeMs: time.Since(startTime).Milliseconds(),
	}
}

func (e *Engine) createErrorResponse(statusCode int, errorMsg string, startTime time.Time) *HTTPResponse {
	return &HTTPResponse{
		StatusCode:     statusCode,
		Error:          errorMsg,
		ResponseTimeMs: time.Since(startTime).Milliseconds(),
	}
}

func (e *Engine) updateAverageLatency(latency time.Duration) {
	totalRequests := e.metrics.TotalRequests
	if totalRequests == 1 {
		e.metrics.AverageLatency = latency
	} else {
		newAvg := (e.metrics.AverageLatency.Seconds()*float64(totalRequests-1) + latency.Seconds()) / float64(totalRequests)
		e.metrics.AverageLatency = time.Duration(newAvg * float64(time.Second))
	}
}

// GetMetrics 获取代理指标
func (e *Engine) GetMetrics() *Metrics {
	return e.metrics
}

// ResetMetrics 重置代理指标
func (e *Engine) ResetMetrics() {
	e.metrics = &Metrics{}
}